// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境

// 获取标签列表
const getTagList = async () => {
  try {
    const db = cloud.database();
    // 读取所有标签
    const tags = await db.collection('tags').get();
    
    // 遍历每个标签，查询对应的单词数量
    const promises = tags.data.map(async (tag) => {
      const countResult = await db.collection('words')
        .where({
          tags: db.command.in([tag.name])
        })
        .count();
      return {
        title: tag.title,
        count: countResult.total,
        tagid: tag.name
      };
    });
    
    // 等待所有查询完成
    const result = await Promise.all(promises);
    
    return {
      success: true,
      data: result
    };
  } catch (error) {
    // 处理错误
    return {
      success: false,
      error: error.message
    };
  }
};

// 获取学习进度统计
const getStudyStatistics = async () => {
  try {
    const db = cloud.database();
    const wxContext = cloud.getWXContext();
    const openid = wxContext.OPENID;
    const _ = db.command;

    // 1. 获取用户当前词典信息
    const userRes = await db.collection('users').where({
      openid: openid
    }).get()
    
    if (userRes.data.length == 0) {
      return { error: '用户不存在' }
    }
    
    const currentWordbook = userRes.data[0].currentwordbook
    
    // 2. 获取当前词典标签信息
    const tagRes = await db.collection('tags').where({
      title: currentWordbook
    }).get()
    
    if (tagRes.data.length == 0) {
      return { error: '未找到对应的词典标签' }
    }
    
    const tagName = tagRes.data[0].name
    
    // 3. 计算词库单词总数（当前词典的所有单词）
    const wordCountRes = await db.collection('words').where({
      tags: db.command.in([tagName])
    }).count()
    
    const totalWordsInLibrary = wordCountRes.total
    
    // 4. 获取用户的所有记忆记录
    const memoryRes = await db.collection('user_memory').where({
      user_id: openid
    }).get()
    
    const allMemoryRecords = memoryRes.data
    const totalLearnedWords = allMemoryRecords.length // 已学习单词总量
    
    // 5. 获取当前词库中的所有单词ID
    // const wordIdsRes = await db.collection('words').where({
    //   tags: db.command.in([tagName])
    // }).field({ _id: true }).get()
    const batchTimes = Math.ceil(wordCountRes.total / 100);
    const tasks = [];
    for (let i = 0; i < batchTimes; i++) {
      const promise = db.collection('words')
        .where({ 
          // 原查询条件
          tags: _.in([tagRes.data[0].name]) 
        })
        .skip(i * 100)
        .limit(100)
        .field({ _id: true })
        .get();
      tasks.push(promise);
    }
    
    // 合并分页结果
    const wordIdsRes = (await Promise.all(tasks))
      .reduce((acc, cur) => acc.concat(cur.data), []);
    
    const wordIdsInLibrary = wordIdsRes.map(item => item._id)
    
    // 6. 计算词库已学习单词数量（在当前词库中的单词）
    const wordIdsSet = new Set(wordIdsInLibrary);
    const learnedInLibrary = allMemoryRecords.filter(record => 
      wordIdsSet.has(record.word_id)
    ).length;

    // 7. 计算词库待学习单词数量
    const toLearnInLibrary = totalWordsInLibrary - learnedInLibrary
    
    // 8. 计算待复习单词数量（学习次数小于8次，并且next_review_at小于当前时间）
    const toReviewCount = allMemoryRecords.filter(record => 
      record.study_times < 8 && record.next_review_at < Date.now()
    ).length
    
    // 返回统计结果
    return {
      success: true,
      data: {
        totalWordsInLibrary,    // 词库单词总数
        toLearnInLibrary,       // 词库待学习单词数量
        learnedInLibrary,       // 词库已学习单词数量
        toReviewCount,          // 待复习单词数量
        totalLearnedWords,      // 已学习单词总量
        openid: openid          // 用户openid（可选，用于调试）
      }
    };
  } catch (error) {
    // 处理错误
    return {
      success: false,
      error: error.message
    };
  }
};

// 获取标签列表
const getWordsToStudy = async () => {
  console.log('getWordsToStudy')
  const db = cloud.database();
  const _ = db.command;

  try {
    // 获取当前用户的 openid
    const wxContext = cloud.getWXContext()
    const openid = wxContext.OPENID

    // 从users集合中获取currentwordbook
    const userRes = await db.collection('users').where({ openid }).get();
    if (!userRes.data.length || !userRes.data[0].currentwordbook) {
      return {
        success: false,
        message: '用户记录不存在或当前词典未设置'
      };
    }
    const user = userRes.data[0];

    // 从tags集合中获取对应的name
    const tagRes = await db.collection('tags').where({ title: user.currentwordbook }).get();
    if (!tagRes.data.length || !tagRes.data[0].name) {
      return {
        success: false,
        message: '词典对应的标签不存在'
      };
    }
    const tag = tagRes.data[0];

    // 构造查询条件
    const excludedIds = await getExcludedWordIds(openid);
    
    // 普通查询代替聚合查询
    const wordsRes = await db.collection('words')
      .where({
        tags: _.in([tagRes.data[0].name]),
        _id: _.nin(excludedIds)
      })
      .orderBy('commonality', 'desc')
      .orderBy('difficulty', 'asc')
      .limit(100)
      .field({ /* 指定返回字段 */ })
      .get();

    console.log(wordsRes)
    // 返回结果
    return {
      success: true,
      data: wordsRes.data
    };
  } catch (error) {
    console.error('获取单词列表失败:', error.message);
    // 处理错误
    return {
      success: false,
      error: error.message
    };
  }
};

// 获取待复习单词列表
const getWordsToReview = async () => {
  console.log('getWordsToReview')
  const db = cloud.database();
  const _ = db.command;

  try {
    // 获取当前用户的 openid
    const wxContext = cloud.getWXContext()
    const openid = wxContext.OPENID

    // 1. 获取用户需要复习的单词记录（next_review_at小于当前时间）
    const memoryRes = await db.collection('user_memory')
      .where({
        user_id: openid,
        next_review_at: _.lt(new Date()) // 下次复习时间小于当前时间
      })
      .orderBy('next_review_at', 'asc') // 按下次复习时间升序
      .orderBy('study_times', 'asc') // 按学习次数升序
      .orderBy('last_reviewed_at', 'asc') // 按最后复习时间升序
      .limit(10) // 限制10条记录
      .get()
    
    if (memoryRes.data.length === 0) {
      return {
        success: true,
        message: '暂无需要复习的单词',
        data: []
      }
    }
    
    // 2. 提取所有word_id用于查询words集合
    const wordIds = memoryRes.data.map(item => item.word_id)
    
    // 3. 查询words集合获取单词详细信息
    const wordsRes = await db.collection('words')
      .where({
        _id: _.in(wordIds)
      })
      .get()
    
    // 4. 创建wordId到单词信息的映射
    const wordMap = {}
    wordsRes.data.forEach(word => {
      wordMap[word._id] = {
        translation: word.translation,
        pronunciation: word.pronunciation,
        sound_url: word.sound_url
      }
    })
    
    // 5. 合并数据
    const reviewWords = memoryRes.data.map(memoryItem => {
      const wordInfo = wordMap[memoryItem.word_id] || {}
      
      return {
        // 用户记忆本信息
        _id: memoryItem._id,
        word: memoryItem.word,
        word_id: memoryItem.word_id,
        study_times: memoryItem.study_times,
        // 从words集合合并的信息
        translation: wordInfo.translation || '',
        pronunciation: wordInfo.pronunciation || '',
        sound_url: wordInfo.sound_url || ''
      }
    })
    
    // 6. 返回结果
    return {
      success: true,
      message: '获取成功',
      data: reviewWords,
      count: reviewWords.length
    }

  } catch (error) {
    console.error('获取单词列表失败:', error.message);
    // 处理错误
    return {
      success: false,
      error: error.message
    };
  }
};

// 新增工具函数
const getExcludedWordIds = async (openid) => {
  try {
    const db = cloud.database();
    
    // 分页获取所有已学单词ID
    const MAX_LIMIT = 100;
    const countRes = await db.collection('user_memory')
      .where({ user_id: openid })
      .count();
    
    const batchTimes = Math.ceil(countRes.total / MAX_LIMIT);
    const tasks = [];
    
    for (let i = 0; i < batchTimes; i++) {
      const promise = db.collection('user_memory')
        .where({ user_id: openid })
        .skip(i * MAX_LIMIT)
        .limit(MAX_LIMIT)
        .field({ word_id: true, _id: false })
        .get();
      tasks.push(promise);
    }
    
    // 合并所有分页数据
    const res = await Promise.all(tasks);
    return res.reduce((acc, cur) => acc.concat(cur.data.map(x => x.word_id)), []);
  } catch (e) {
    console.error('获取排除单词列表失败:', e);
    return [];
  }
};

// 标记单词为已掌握
const studyWord = async (event) => {
  console.log('studyWord', event)
  try {
    const db = cloud.database();
    const wxContext = cloud.getWXContext()
    const openid = wxContext.OPENID

    // 从入参中获取word
    const { word } = event;

    // 查询words集合，获取对应的word_id
    const wordRes = await db.collection('words')
      .where({ word: word })
      .get();
    if (!wordRes.data || wordRes.data.length == 0) {
      return {
        success: false,
        message: '未找到对应的单词记录'
      };
    }
    const wordDoc = wordRes.data[0];

    // 当前时间
    const now = new Date().toISOString();
    // 20分钟后的时间
    const nextReviewAt = db.serverDate({
      offset: 20 * 60 * 1000 // 20分钟后的服务端时间
    });

    // 插入新的记录
    const result = await db.collection('user_memory').add({
      data: {
        user_id: openid,
        word: word,
        word_id: wordDoc._id,
        status: '需要复习',
        added_at: db.serverDate(),
        study_times: 1,
        last_reviewed_at: null,
        next_review_at: nextReviewAt
      }
    });

    // 返回成功结果
    return {
      success: true,
      data: result
    };
  } catch (error) {
    // 处理错误
    return {
      success: false,
      error: error.message
    };
  }
};

// 单词复习
const reviewWord = async (event) => {
  console.log('reviewWord', event)
  const wxContext = cloud.getWXContext()
  const openid = wxContext.OPENID // 获取用户openid
  const db = cloud.database()
  const _ = db.command

  try {
    // 1. 查询用户的记忆记录
    const memoryRes = await db.collection('user_memory')
      .where({
        user_id: openid,
        word: event.word
      })
      .get()
    
    if (memoryRes.data.length === 0) {
      return {
        success: false,
        message: '未找到对应的单词记录'
      }
    }
    
    const memoryRecord = memoryRes.data[0]
    const currentStudyTimes = memoryRecord.study_times
    const newStudyTimes = currentStudyTimes + 1
    
    // 2. 计算下次复习时间
    const now = new Date()
    let nextReviewAt = new Date(now)
    
    // 根据study_times确定时间间隔
    switch (newStudyTimes) {
      case 2:
        nextReviewAt.setHours(now.getHours() + 1) // 延后1小时
        break
      case 3:
        nextReviewAt.setHours(now.getHours() + 9) // 延后9小时
        break
      case 4:
        nextReviewAt.setDate(now.getDate() + 1) // 延后1天
        break
      case 5:
        nextReviewAt.setDate(now.getDate() + 2) // 延后2天
        break
      case 6:
        nextReviewAt.setDate(now.getDate() + 6) // 延后6天
        break
      case 7:
        nextReviewAt.setDate(now.getDate() + 31) // 延后31天
        break
      default:
        nextReviewAt = now // 其他情况使用当前时间
    }
    
    // 3. 准备更新数据
    const updateData = {
      study_times: newStudyTimes,
      last_reviewed_at: now,
      next_review_at: nextReviewAt
    }
    
    // 4. 如果学习次数达到8次，更新状态为"已掌握"
    if (newStudyTimes === 8) {
      updateData.status = "已掌握"
    }
    
    // 5. 更新数据库记录[6](@ref)
    const updateRes = await db.collection('user_memory')
      .doc(memoryRecord._id)
      .update({
        data: updateData
      })
    if (!updateRes) {
      return {
        success: false,
        message: '更新失败'
      }
    } else {
      return {
        success: true,
        message: '更新成功',
        data: {
          _id: memoryRecord._id,
          word: memoryRecord.word,
          study_times: newStudyTimes,
          next_review_at: nextReviewAt,
          last_reviewed_at: now,
          status: newStudyTimes === 8 ? "已掌握" : memoryRecord.status
        }
      }
    }
  } catch (error) {
    // 处理错误
    return {
      success: false,
      error: error.message
    };
  }
};

// 云函数入口函数
exports.main = async (event, context) => {
  console.log(event)
  switch (event.type) {
    case "getTagList":
      return await getTagList();
    case "getWordsToStudy":
      return await getWordsToStudy();
    case "getWordsToReview":
      return await getWordsToReview();
    case "studyWord":
      return await studyWord(event);
    case "reviewWord":
      return await reviewWord(event);
    case "getStudyStatistics":
      return await getStudyStatistics();
  }
}